const rgbWhite = { r: 255, g: 255, b: 255 };
const rgbBlack = { r: 0, g: 0, b: 0 };

function componentToHex(c) {
  const hex = Math.round(c).toString(16);
  return hex.length === 1 ? '0' + hex : hex;
}

function rgbToHex(rgb) {
  return `#${componentToHex(rgb.r)}${componentToHex(rgb.g)}${componentToHex(rgb.b)}`;
}

function mix(color, mixColor, weight) {
  return {
    r: color.r * (1 - weight) + mixColor.r * weight,
    g: color.g * (1 - weight) + mixColor.g * weight,
    b: color.b * (1 - weight) + mixColor.b * weight,
  };
}

/**
 * hex 转换为 rgb
 * @param hex 例如 #FF0000
 */
function hexToRGB(hex) {
  if (!/^[0-9A-Fa-f]{3}$|[0-9A-Fa-f]{6}$/.test(hex)) throw new Error("请传入合法的16进制颜色值，eg: #FF0000");
  hex = hex.replace('#', ''); // 移除可能存在的 # 符号
  // 确保十六进制代码是有效的
  // 返回 RGB 对象
  return {
    r: parseInt(hex.slice(0, 2), 16),
    g: parseInt(hex.slice(2, 4), 16),
    b: parseInt(hex.slice(4, 6), 16)
  };
}

/**
 * 获取指定偏移量的变浅/变深颜色
 * @param hexColor 原始颜色，如 '#6340ff'
 * @param offset 偏移量，1.0 表示不变，<1.0 变浅，>1.0 变深
 * @returns {string} 新的十六进制颜色值
 */
function getOffsetColor(hexColor, offset = 1.0) {
  const rgb = hexToRGB(hexColor);
  let targetColor;

  if (offset < 1.0) {
    // 变浅：与白色混合，权重为 (1 - offset)
    targetColor = mix(rgb, rgbWhite, 1 - offset);
  } else if (offset > 1.0) {
    // 变深：与黑色混合，权重为 (offset - 1)
    targetColor = mix(rgb, rgbBlack, offset - 1);
  } else {
    // offset === 1.0，颜色不变
    targetColor = rgb;
  }

  return rgbToHex(targetColor);
}

/**
 * 计算颜色的相对亮度（0 ~ 1），用于判断是否为亮色
 * @param {number} r 红色分量 (0~255)
 * @param {number} g 绿色分量 (0~255)
 * @param {number} b 蓝色分量 (0~255)
 * @returns {number} 亮度值（0 ~ 1）
 */
function getLuminance(r, g, b) {
  const linearize = c => {
    c /= 255;
    return c <= 0.03928 ? c / 255 / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
  };

  return 0.2126 * linearize(r) + 0.7152 * linearize(g) + 0.0722 * linearize(b);
}

function isLightColor(hexColor) {
  const rgb = hexToRGB(hexColor);
  const luminance = getLuminance(rgb.r, rgb.g, rgb.b);
  return luminance > 0.5; // true 表示亮色，false 表示暗色
}

const getElementPlusThemeColors = (type, baseColor) => {
  const lightColor = isLightColor(baseColor);
  if (type == 'primary' || type == 'success' || type == 'warning' || type == 'danger' || type == 'info') {
    return [
      { varName: `--el-color-${type}`, color: getOffsetColor(baseColor, 1) },
      { varName: `--el-color-${type}-dark-2`, color: getOffsetColor(baseColor, 1.2) },
      { varName: `--el-color-${type}-light-3`, color: getOffsetColor(baseColor, 0.7) },
      { varName: `--el-color-${type}-light-5`, color: getOffsetColor(baseColor, 0.5) },
      { varName: `--el-color-${type}-light-7`, color: getOffsetColor(baseColor, 0.3) },
      { varName: `--el-color-${type}-light-8`, color: getOffsetColor(baseColor, 0.22) },
      { varName: `--el-color-${type}-light-9`, color: getOffsetColor(baseColor, 0.15) },
    ]
  }
  if (type == 'text') {
    const textBaseColor = lightColor ? '#333333' : '#ffffff';
    return [
      { varName: `--el-text-color-primary`, color: getOffsetColor(textBaseColor, 1) },
      { varName: `--el-text-color-regular`, color: getOffsetColor(textBaseColor, lightColor ? 0.8 : 1.1) },
      { varName: `--el-text-color-secondary`, color: getOffsetColor(textBaseColor, lightColor ? 0.6 : 1.2) },
      { varName: `--el-text-color-placeholder`, color: getOffsetColor(textBaseColor, lightColor ? 0.4 : 1.3) },
      { varName: `--el-text-color-disabled`, color: getOffsetColor(textBaseColor, lightColor ? 0.2 : 1.3) },
    ]
  }
  if (type == 'bg') {
    return [
      { varName: `--el-bg-color`, color: getOffsetColor(baseColor, 1) },
      { varName: `--el-bg-color-page`, color: getOffsetColor(baseColor, lightColor ? 1.04 : 1.2) },
      { varName: `--el-bg-color-overlay`, color: getOffsetColor(baseColor, lightColor ? 1: 0.9) },
    ]
  }
  if (type == 'border' || type == 'fill') {
    if (type == 'border') baseColor = lightColor ? getOffsetColor(baseColor, 1.1) : getOffsetColor(baseColor, 0.8);
    return [
      { varName: `--el-${type}-color`, color: getOffsetColor(baseColor, 1) },
      { varName: `--el-${type}-color-light`, color: getOffsetColor(baseColor, lightColor ? 1.04 : 0.95) },
      { varName: `--el-${type}-color-lighter`, color: getOffsetColor(baseColor, lightColor ? 1.08 : 0.9) },
      { varName: `--el-${type}-color-extra-light`, color: getOffsetColor(baseColor, lightColor ? 1.12 : 0.85) },
      { varName: `--el-${type}-color-dark`, color: getOffsetColor(baseColor, 1.05) },
      { varName: `--el-${type}-color-darker`, color: getOffsetColor(baseColor, 1.1) },
    ].concat(type == 'fill' ? [{ varName: `--el-fill-color-blank`, color: lightColor ? baseColor : 'transparent' }] : [])
  }
  if (type == 'mask') {
    return [
      { varName: `--el-mask-color`, color: getOffsetColor(baseColor, 1) }, // 需要固定透明度0.8
      { varName: `--el-mask-color-extra-light`, color: getOffsetColor(baseColor, 0.4) }, // 需要固定透明度0.3
    ]
  }
  return [];
}

/**
 * 修改 element-plus的颜色主题
 * @param type primary | success | warning | danger | info | bg
 * @param baseColor
 */
function updateElementPlusTheme(type, baseColor) {
  if (type === 'primary') {
    const primaryColors = getElementPlusThemeColors('primary', baseColor);
    primaryColors.forEach((item) => {
      document.documentElement.style.setProperty(item.varName, item.color);
    });
    return;
  }
  const bgColors = getElementPlusThemeColors('bg', baseColor);
  const textColors = getElementPlusThemeColors('text', baseColor);
  const borderColors = getElementPlusThemeColors('border', baseColor);
  const fillColors = getElementPlusThemeColors('fill', baseColor);

  // console.log(JSON.stringify(colorList.reduce((acc, item) => {
  //   acc[item.varName] = item.color;
  //   return acc;
  // }, {}), null, 2));
  
  [...bgColors, ...textColors, ...borderColors, ...fillColors].forEach(item => {
    document.documentElement.style.setProperty(item.varName, item.color);
  })
}

export {
  hexToRGB,
  rgbToHex,
  updateElementPlusTheme
}